package com.ifonly.core;

import com.ifonly.common.ViewType;
import com.ifonly.config.Configuration;
import com.ifonly.handler.Handler;
import com.ifonly.handler.HandlerFactory;
import com.ifonly.handler.Handlers;
import com.ifonly.interceptor.GlobalInterceptors;
import com.ifonly.logger.Logger;
import com.ifonly.mvc.ActionHandler;
import com.ifonly.mvc.ActionMapper;
import com.ifonly.plugin.Plugin;
import com.ifonly.plugin.Plugins;
import com.ifonly.render.MainRenderFactory;
import com.ifonly.render.RenderFactory;
import com.ifonly.render.renders.FtlRender;

import javax.servlet.ServletContext;

/**
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-09 14:25
 * @since JDK 1.6
 */
public class IfOnly {

    // ~~ IfOnly 采用单例模式 ~~

    private IfOnly() {
    }

    private static class InstanceHolder {
        public static IfOnly instance = new IfOnly();
    }

    public static IfOnly getInstance() {
        return InstanceHolder.instance;
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 属性信息
    private ClassContainer classContainer = ClassContainer.getInstance();

    private Configuration config = Configuration.getInstance();

    private ActionMapper actionMapper = ActionMapper.getInstance();
    private GlobalInterceptors interceptors = GlobalInterceptors.getInstance();
    private Plugins plugins = Plugins.getInstance();
    private Handlers handlers = Handlers.getInstance();

    private ServletContext servletContext;
    private IfOnlyConfig ifOnlyConfig;

    private Logger logger;

    private Handler handler;

    /**
     * IfOnly 初始化
     *
     * @param servletContext 上下文环境
     * @param ifOnlyConfig   ifonly 启动配置类
     * @return true-初始化成功|false-初始化失败
     */
    public boolean init(ServletContext servletContext,
                        IfOnlyConfig ifOnlyConfig) {

        this.servletContext = servletContext;
        this.ifOnlyConfig = ifOnlyConfig;

        initLogger();

        ifOnlyConfig.configAction(actionMapper);
        ifOnlyConfig.configInterceptor(interceptors);
        ifOnlyConfig.configPlugin(plugins);
        startPlugins();
        ifOnlyConfig.configHandler(handlers);
        initHandlers();

        initRender();

        classContainer.destroy();
        logger.debug("IfOnly.init finish...");
        return true;
    }

    private void initRender() {
        MainRenderFactory factory = ViewType.getMainRenderFactory(config.getViewType());
        RenderFactory.setMainRenderFactory(factory);
        FtlRender.initFreemarker(servletContext, config.getLocale(), config.getFtlTemplateUpdateDelay());
    }

    public Handler getHandler() {
        return this.handler;
    }

    private void initHandlers() {
        handler = HandlerFactory.getHandler(handlers.getHandlers(), new ActionHandler());
    }

    private void startPlugins() {
        for (Plugin plugin : plugins.getPlugins()) {
            plugin.start();
        }
    }

    private void initLogger() {
        logger = Logger.getLogger(IfOnly.class);

        ifOnlyConfig.initLogger();
    }

}
